package com.summer.mall.controller.admin;

import com.summer.mall.common.Const;
import com.summer.mall.common.ResponseService;
import com.summer.mall.entity.*;
import com.summer.mall.service.UserService;
import com.summer.mall.util.ResultUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpSession;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

@RestController
@RequestMapping("/chat")
public class ChatController {
    private List<Customer> customerWaitList = new ArrayList<>();
    private List<Customer> customerClientList = new ArrayList<>();
    private List<CustomService> customServiceClientList = new ArrayList<>();

    @Autowired
    private UserService userService;

    @Autowired
    private HttpSession session;

    @PostMapping(value = "/login")
    @ResponseBody
    public ResponseService<User> login(@RequestParam String username, @RequestParam String password, HttpSession session) {
        ResponseService<User> response = userService.login(username, password);

        if (response.isSuccess()) {
            session.setAttribute(Const.CURRENT_USER ,response.getData());
            return response;
        }
        return response;
    }

    //检测用户是否已登录
    @GetMapping("/loggedIn")
    public Result loggedIn() {
        User temp = (User)session.getAttribute(Const.CURRENT_USER);
        if (temp != null) {
            return ResultUtil.success(temp);
        }
        else {
            return ResultUtil.failure("fail.");
        }
    }

    //用户发送请求客服
    @GetMapping("/pushCustomServiceRequest")
    public Result pushCustomServiceRequest() {
        User temp = (User)session.getAttribute(Const.CURRENT_USER);
        if (temp == null) {
            return ResultUtil.failure("not login.");
        }
        Customer temp1 = getCustomerFromListBySessionId(customerClientList, session.getId());
        if (temp1 != null) {
            Customer temp2 = getCustomerFromListBySessionId(customerWaitList, session.getId());
            if (temp2 == null && temp1.getCustomService() == null) {
                customerWaitList.add(temp1);
            }
            return ResultUtil.success();
        }
        Customer customer = new Customer(temp, getUnixTimesTamp());
        customer.setSessionId(session.getId());
        customerWaitList.add(customer);
        customerClientList.add(customer);
        System.out.println(temp.getUsername() + " request custom service. " + customerClientList.size() + " customers.");

        return ResultUtil.success();
    }

    //用户获取是否已被客服接收
    @GetMapping("/getCustomService")
    public Result getCustomService() {
        User temp = (User)session.getAttribute(Const.CURRENT_USER);
        if (temp == null) {
            return ResultUtil.failure("not login.");
        }
        Customer customer = getCustomerFromListBySessionId(customerClientList, session.getId());
        if (customer != null && customer.getCustomService() != null) {
            customer.setLastTime(getUnixTimesTamp());
            return ResultUtil.success(customer.getCustomService());
        }
        else if (customer != null) {
            customer.setLastTime(getUnixTimesTamp());
        }
        else {

            return ResultUtil.failure("Error.");
        }
        return ResultUtil.failure("not found");
    }

    //用户接收信息
    @PostMapping("/getMsg")
    public Result getMsg() {
        User temp = (User)session.getAttribute(Const.CURRENT_USER);
        if (temp == null) {
            return ResultUtil.failure("not login.");
        }
        Customer customer = getCustomerFromListBySessionId(customerClientList, session.getId());
        if (customer != null) {
            customer.setLastTime(getUnixTimesTamp());
            List<ChatMsg> chatMsgList = customer.getChatMsgArray();
            List<ChatMsg> copyList = listDeepCopy(chatMsgList);
            chatMsgList.clear();
            return ResultUtil.success(copyList);
        }
        return ResultUtil.failure("not found.");
    }

    //客户发送信息给客服
    @PostMapping("/sendMsg")
    public Result sendMsg(String msg) {
        User temp = (User)session.getAttribute(Const.CURRENT_USER);
        if (temp == null) {
            return ResultUtil.failure("not login.");
        }
        Customer customer = getCustomerFromListBySessionId(customerClientList, session.getId());
        if (customer != null) {
            CustomService customService = customer.getCustomService();
            if (customService != null) {
                Integer csId = customService.getCs_id();
                customService.getChatMsgArray().add(new ChatMsg(1, msg, csId, customer.getSessionId()));
                return ResultUtil.success();
            }
            return ResultUtil.failure("CustomService not found.");
        }
        return ResultUtil.failure("not found.");
    }

    //检测客服是否已登录
    @GetMapping("/cs/loggedIn")
    public Result csLoggedIn() {
        CustomService temp = (CustomService) session.getAttribute("customService");
        if (temp != null) {
            return ResultUtil.success(temp);
        }
        else {
            return ResultUtil.failure("fail.");
        }
    }

    @GetMapping("/csPushCustomService")
    public Result csPushCustomService() {
        CustomService temp = (CustomService) session.getAttribute("customService");
        if (temp == null) {
            return ResultUtil.failure("not login.");
        }
        CustomService customService = getCustomServiceFromListBySessionId(customServiceClientList, session.getId());
        if (getCustomServiceFromListBySessionId(customServiceClientList, session.getId()) != null) {
            return ResultUtil.success(customService.getCustomerList());
        }
        temp.setSessionId(session.getId());
        temp.setLastTime(getUnixTimesTamp());
        customServiceClientList.add(temp);
        return ResultUtil.success();
    }

    //客服接收用户
    @GetMapping("/csGetCustomer")
    public Result csGetCustomer() {
        CustomService temp = (CustomService) session.getAttribute("customService");
        if (temp == null) {
            return ResultUtil.failure("not login.");
        }
        if (customerWaitList.size() == 0) {
            return ResultUtil.failure("no customer now.");
        }
        CustomService customService = getCustomServiceFromListBySessionId(customServiceClientList, session.getId());
        if (customService != null) {
            Customer customer = customerWaitList.get(0);
            customerWaitList.remove(0);
            customer.setCustomService(customService);
            customService.getCustomerList().add(customer);
            return ResultUtil.success(customer);
        }
        return ResultUtil.failure("not found");
    }

    //客服接收信息
    @PostMapping("/csGetMsg")
    public Result csGetMsg() {
        CustomService temp = (CustomService) session.getAttribute("customService");
        if (temp == null) {
            return ResultUtil.failure("not login.");
        }
        CustomService customService = getCustomServiceFromListBySessionId(customServiceClientList, session.getId());
        if (customService != null) {
            customService.setLastTime(getUnixTimesTamp());
            List<ChatMsg> chatMsgList = customService.getChatMsgArray();
            List<ChatMsg> copyList = listDeepCopy(customService.getChatMsgArray());
            chatMsgList.clear();
            return ResultUtil.success(copyList);
        }
        return ResultUtil.failure("not found.");
    }

    //客服发送信息给客户
    @PostMapping("/csSendMsg")
    public Result csSendMsg(String customerSessionId, String msg) {
        CustomService temp = (CustomService) session.getAttribute("customService");
        if (temp == null) {
            return ResultUtil.failure("not login.");
        }
        CustomService customService = getCustomServiceFromListBySessionId(customServiceClientList, session.getId());
        if (customService != null) {
            Customer customer = getCustomerFromListBySessionId(customService.getCustomerList(), customerSessionId);
            if (customer != null) {
                customer.getChatMsgArray().add(new ChatMsg(1, msg, customService.getCs_id()));
                return ResultUtil.success();
            }
            return ResultUtil.failure("user not found.");
        }
        return ResultUtil.failure("not found.");
    }

    //客服结束对话
    @PostMapping("/csEndChat")
    public Result csEndChat(String customerSession) {
        CustomService temp = (CustomService) session.getAttribute("customService");
        if (temp == null) {
            return ResultUtil.failure("not login.");
        }
        CustomService customService = getCustomServiceFromListBySessionId(customServiceClientList, session.getId());
        if (customService != null) {
            Customer customer = getCustomerFromListBySessionId(customService.getCustomerList(), customerSession);
            if (customer != null) {
                customService.getCustomerList().remove(customer);
                customer.getChatMsgArray().add(new ChatMsg(2, "Chat END.", customService.getCs_id()));
                customer.setCustomService(null);
                return ResultUtil.success();
            }
            return ResultUtil.failure("user not found");
        }
        return ResultUtil.failure("not found.");
    }

    //连接的心跳包
    @Scheduled(cron="0/1 * * * * ?")
    public void clientHeartBeat() {
        Long currentUnixTimesTamp = getUnixTimesTamp();
        Iterator<Customer> it = customerClientList.iterator();
        while (it.hasNext()) {
            Customer item = it.next();
            if (currentUnixTimesTamp - item.getLastTime() > 5) {
                System.out.println("Customer " + item.getUser_name() + " disconnect.");
                it.remove();
                if (item.getCustomService() != null) {
                    /*
                     * 留作处理如果用户已与客服交流时的情况
                     * */
                }
                else {
                    for (Customer item1 : customerWaitList) {
                        if (item1.getUser_id().equals(item.getUser_id())) {
                            customerWaitList.remove(item1);
                            break;
                        }
                    }
                }
            }
        }
        Iterator<CustomService> it1 = customServiceClientList.iterator();
        while (it1.hasNext()) {
            CustomService item = it1.next();
            if (currentUnixTimesTamp - item.getLastTime() > 5) {
                System.out.println("CustomService " + item.getCs_name() + " disconnect.");
                it1.remove();
                if (item.getCustomerList().size() != 0) {
                    /*
                    * 客服断线时的处理
                    * */
                    for (Customer c1 : item.getCustomerList()) {
                        c1.setCustomService(null);
                        c1.getChatMsgArray().add(new ChatMsg(2, "Custom Service Disconnect.", item.getCs_id()));
                    }
                }
            }
        }
    }

    private Customer getCustomerFromListById(List<Customer> list, Integer user_id) {
        for (Customer item : list) {
            if (item.getUser_id().equals(user_id))
                return item;
        }
        return null;
    }

    //用于找Customer列表中的单个子项目
    private Customer getCustomerFromListBySessionId(List<Customer> list, String sessionId) {
        for (Customer item : list) {
            if (item.getSessionId().equals(sessionId)) {
                return item;
            }
        }
        return null;
    }

    //用于找CustomService列表中的单个子项目
    private CustomService getCustomServiceFromListBySessionId(List<CustomService> list, String sessionId) {
        for (CustomService item : list) {
            if (item.getSessionId().equals(sessionId)) {
                return item;
            }
        }
        return null;
    }

    //获取当时的时间戳
    private Long getUnixTimesTamp() {
        return  System.currentTimeMillis() / 1000;
    }

    private void customerDisconnect() {

    }

    //用于列表的深拷贝
    private <T> List<T> listDeepCopy(List<T> list) {
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        try {
            ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
            objectOutputStream.writeObject(list);
            ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
            ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream);
            return (List<T>)objectInputStream.readObject();
        }
        catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}
